<template>
  <div style="border: 1px solid #ccc; z-index: 999999999999">
    <div :id="toolbarId"></div>
    <div :id="editorId" :style="getEditorStyle"></div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, unref, watch } from 'vue';
import { useRuleFormItem } from '@/hooks/component/use-form-item';
import '@wangeditor/editor/dist/css/style.css';
import { createEditor, createToolbar, IEditorConfig, IDomEditor, IToolbarConfig } from '@wangeditor/editor';
import { onBeforeUnmount, ref, shallowRef, onMounted } from 'vue';
import { isJSON } from 'class-validator';
import { getRandom } from '@pkg/utils';
import {getGlobalConfig} from "@/internal";
import { context } from '@pkg/request/bridge';
export default defineComponent({
  name: 'WangEditor',
  //不将 attrs 的属性绑定到 html 标签上
  inheritAttrs: false,
  props: {
    value: {
      type: [String, Array, Object] as any,
    },
    valueType: {
      type: String,
      default: 'html',
    },
    height: {
      type: Number,
      default: 300,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['change', 'update:value'],
  setup(props, { emit, attrs }) {
    const globSetting = getGlobalConfig();
    const toolbarId="toolbar-container"+getRandom(10);
    const editorId="editor-container"+getRandom(10);
    const emitData = ref<any>();
    //表单值
    const [state] = useRuleFormItem(props, 'value', 'change', emitData);
    //是否是初始加载
    const isInitFirst = ref(true);
    // 编辑器实例，必须用 shallowRef
    const editorRef = shallowRef();
    // 合并 props 和 attrs
    const bindProps: any = computed(() => Object.assign({}, props, attrs));
    onMounted(() => {
      let value = props.value || '<p></p>';
      initEditor(value, 'HTML');
    });

    // 组件销毁时，也及时销毁编辑器
    onBeforeUnmount(() => {
      console.info('editorRef', editorRef.value);
      const editor = editorRef.value;
      if (editor == null) return;
      editor.destroy();
    });

    /**
     * 监听组件值
     */
    watch(
      () => props.value,
      (val) => {
        //编辑时触发一次
        if (props.value && isInitFirst.value) {
          initValue();
        }
      },
    );

    /**
     * 组件赋值
     */
    function initValue() {
      isInitFirst.value = false;
      let value = unref(props.value);
      if (isJSON(value)) {
        console.info("WangEdit:JSON:",value);
        initEditor(JSON.parse(value), 'JSON');
      } else {
        console.info("WangEdit:HTML:",value);
        initEditor(value, 'HTML');
      }
    }

    /**
     * 初始化编辑器
     * @param value
     * @param valueType
     */
    function initEditor(value, valueType) {
      const token = context.getTokenFunction?.();
      // 编辑器配置
      const editorConfig: Partial<IEditorConfig> = {
        MENU_CONF:{
          uploadImage:{
            server: globSetting.uploadUrl,
            fieldName: 'file',
            headers: {
              'Authorization': token,
            },
            // 自定义插入图片
            customInsert(res: any, insertFn: any) {
             insertFn(res.data.ossPath)
            },
          },
        }
      };
      editorConfig.placeholder = '请输入内容';
      editorConfig.onChange = (editor: IDomEditor) => {
        // 当编辑器选区、内容变化时，即触发
        if (props.valueType == 'json') {
          let val = JSON.stringify(editor.children);
          handleChange(val);
        }
        if (props.valueType == 'html') {
          handleChange(editor.getHtml());
        }
      };
      // 工具栏配置
      const toolbarConfig: Partial<IToolbarConfig> = {
        excludeKeys: ['emotion', 'insertLink', 'group-video', 'codeBlock'],
      };
      let initConfig = {
        selector: '#'+editorId,
        config: editorConfig,
        mode: 'default',
      };
      if (valueType === 'JSON') {
        initConfig = Object.assign(initConfig, { content: value });
      }
      if (valueType === 'HTML') {
        initConfig = Object.assign(initConfig, { html: value });
      }
      if (editorRef.value) {
        editorRef.value.destroy();
      }
      // 创建编辑器
      editorRef.value = createEditor(initConfig);
      // 创建工具栏
      const toolbar = createToolbar({
        editor: editorRef.value,
        selector: '#'+toolbarId,
        config: toolbarConfig,
        mode: 'default',
      });
    }

    //内容修改事件
    function handleChange(value) {
      state.value = value;
      emit('update:value', value);
    }
    //获取编辑器样式
    const getEditorStyle = computed(() => {
      console.info('props.height', props.height);
      return {
        minHeight: props.height + 'px',
      };
    });

    return {
      editorRef,
      // 或 'simple'
      mode: 'default',
      bindProps,
      getEditorStyle,
      toolbarId,
      editorId,
      handleChange,
    };
  },
});
</script>

<style lang="less" scoped>
.full-screen-container {
  z-index: 1000000;
}
</style>
